﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using StockTrader.DAL.HoseAdapter.Lib;
using ZipLibrary.Zip;
using StockTrader.DAL.HnxMonitor.BusinessLogic;
using StockTrader.DAL.HnxMonitor.DataAccess;
using StockTrader.DAL.HnxMonitor.Config;

namespace StockTrader.DAL.HnxMonitor
{
    public partial class frmMain : Form
    {
        private System.Timers.Timer pollTimer = new System.Timers.Timer();
        private DALclient client = new DALclient();
        private AsyncProcessor processor;
        private bool _isRunning = false;
        private bool _cleanData = false;
        private string[] updateList = Settings.UPDATE_LIST.Split(',');
        frmOptions option;
        private string Status;

        public frmMain()
        {
            InitializeComponent();
            option = new frmOptions(this, 0.1f);
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            try
            {
                if (_isRunning)
                {
                    btnRun.Text = "Start";
                    _isRunning = false;
                    pollTimer.Enabled = false;
                }
                else
                {
                    GetData();

                    //TODO: Reset and update UI
                    _isRunning = true;
                    btnRun.Text = "Stop";

                    if (rbRecovery.Checked)
                    {
                        //DataEngine.markets = client.getHnxAllMarketInfo();
                        DataEngine.orders = client.getHnxAllOrders();
                    }

                    //TODO: Start timer
                    pollTimer.Interval = Settings.TRADING_INTERVAL;
                    pollTimer.Enabled = true;
                    pollTimer.Elapsed += new System.Timers.ElapsedEventHandler(pollTimer_Elapse);
                }

            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
                Application.Exit();
            }
        }

        void pollTimer_Elapse(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                UpdateUI();
                switch (Status)
                {
                    case "Opening":
                        Openning();
                        break;
                    case "Accept ATO":
                        Openning();
                        break;
                    case "ATO":
                        Openning();
                        break;
                    case "Trading":
                        pollTimer.Interval = Settings.TRADING_INTERVAL;
                        _isRunning = true;
                        GetData();
                        break;
                    case "Closed":
                        _cleanData = false;
                        pollTimer.Interval = Settings.STATUS_CHECK_INTERVAL;
                        processor = new AsyncProcessor(lblMarketInfo, "MarketInfo");
                        processor.Execute();
                        if ((DateTime.Now - Settings.EOD).TotalSeconds.Equals(Settings.STATUS_CHECK_INTERVAL))
                            client.Backup();
                        break;
                    default:
                        pollTimer.Interval = Settings.TRADING_INTERVAL;
                        _isRunning = true;
                        GetData();
                        break;
                }
            }
            catch (System.Exception ex)
            {
                WriteLog(ex.Message);
            }
        }

        private void Openning()
        {
            pollTimer.Interval = Settings.STATUS_CHECK_INTERVAL;
            if (!_cleanData)
            {
                _cleanData = true;
                client.ClearAll();
            }
            processor = new AsyncProcessor(lblMarketInfo, "MarketInfo");
            processor.Execute();
            processor = new AsyncProcessor(lblStockInfo, "Initialize");
            processor.Execute();
            processor = new AsyncProcessor(lblStockInfo, "TopPrice");
            processor.Execute();
        }

        private void btnRecover_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure want to Clean & ReInsert?", "Hey, dude!",
                MessageBoxButtons.YesNo).Equals(DialogResult.Yes))
            {
                DALclient client = new DALclient();
                client.ClearAll();
                GetData();
                DataEngine.stocks.Clear();
                DataEngine.markets.Clear();
                DataEngine.orders.Clear();
                DataEngine.topprices.Clear();
            }
        }

        private void GetData()
        {
            foreach (string obj in updateList)
            {
                switch (obj)
                {
                    case "Orders":
                        processor = new AsyncProcessor(lblOrder, obj);
                        processor.Execute();
                        break;
                    case "StockInfo":
                        processor = new AsyncProcessor(lblStockInfo, obj);
                        processor.Execute();
                        break;
                    case "MarketInfo":
                        processor = new AsyncProcessor(lblMarketInfo, obj);
                        processor.Execute();
                        break;
                    case "TopPrice":
                        processor = new AsyncProcessor(lblTopPrice, obj);
                        processor.Execute();
                        break;
                }
            }
        }

        private void UpdateUI()
        {
            //TODO: Update list view control
            MethodInvoker MarketStatus = delegate
            {
                if (DataEngine.markets.Count > 0)
                {
                    lblMarket.Text = DataEngine.markets[DataEngine.markets.Count - 1].Status;
                    lblTime.Text = DataEngine.markets[DataEngine.markets.Count - 1].TradingDate.ToString("dd/MM/yyyy");
                    Status = lblMarket.Text;
                }
            };
            if (lblMarket.InvokeRequired || lblTime.InvokeRequired)
            {
                lblMarket.Invoke(MarketStatus);
                lblTime.Invoke(MarketStatus);
            }
            else
                MarketStatus();

        }

        private void WriteLog(string logMsg)
        {
            using (StreamWriter wr = File.AppendText("HNX_version2.txt"))
            {
                lock (wr)
                {
                    wr.Write(DateTime.Now + ": ");
                    wr.WriteLine(logMsg);
                    wr.Flush();
                    wr.Close();
                }
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {

        }

        private void btnOptions_Click(object sender, EventArgs e)
        {
            option.SlideDirection = SlideDialog.SlideDialog.SLIDE_DIRECTION.BOTTOM;
            option.Slide();
        }

    }
}
